# This file is part of PyMXit, a Python library implementing the basic
# functionality of the MXit protocol.
#
# Copyright (C) 2008 Ralf Kistner <ralf.kistner@gmail.com>
# 
# PyMXit is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# PyMXit is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with PyMXit.  If not, see <http://www.gnu.org/licenses/>.

import socket
import sys
import threading
import parser
import select

class Listener(threading.Thread):
    def __init__(self, port, cb):
        threading.Thread.__init__(self)
        self.host = ''
        self.port = port
        self.backlog = 5
        self.server = None
        self.threads = []
        self.cb = cb
        self.running = False
        
        self.open_socket()


    def open_socket(self):
        try:
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.server.bind((self.host,self.port))
            self.server.listen(5)
            self.running = True
        except socket.error, (value,message):
            if self.server:
                self.server.close()
            print "Could not open socket: " + message

    def run(self):
        input = [self.server,sys.stdin]
        running = 1
        while self.running:
            inputready,outputready,exceptready = select.select(input,[],[])

            for s in inputready:

                if s == self.server:
                    # handle the server socket
                    c = Client(self.server.accept(), self.cb)
                    c.start()
                    self.threads.append(c)

                elif s == sys.stdin:
                    # handle standard input
                    junk = sys.stdin.readline()
                    self.stop()
        """
        try:
            while self.running:
                print "listening..."
                c = Client(self.server.accept(), self.cb)
                c.start()
                self.threads.append(c)
        finally:
            self.close()
        """
            
    def stop(self):
        self.running = False
        self.close()
    
    def isopen(self):
        return self.running
    
    def close(self):
        if self.server:
            self.server.close()
        if self.threads:
            for c in self.threads:
                c.join()

class Client(threading.Thread):
    def __init__(self, ca, cb):
        threading.Thread.__init__(self)
        self.ca = ca
        self.cb = cb

    def run(self):
        self.cb(self.ca)

